export function isPlainObject(x: any): boolean {
    return clazz(x) === 'Object'
}

export function isString(x: any): boolean {
    return (x instanceof String) || clazz(x) === 'string'
}

export function isFunction(x: any): boolean {
    return clazz(x) === 'function'
}

function clazz(x: any): string {
    const typeOfClazz = typeof(x)
    if (typeOfClazz === 'object') {
        let matched = /\s*\[object\s*(\S+)\]\s*/.exec(Object.prototype.toString.call(x))
        if (matched && matched[1]) {
            if (matched[1] === 'Object') {
                let matched = /^\s*class\s+(\S+)\s+/.exec(x.__proto__.constructor.toString())
                if (matched && matched[1]) {
                    return matched[1]
                }
            }

            return matched[1]
        }
        else {
            throw Error('Unrecognized class type')
        }
    }
    else {
        return typeOfClazz
    }
}